package options

import (
	"errors"
	"fmt"
	"github.com/spf13/pflag"
	"strings"
)

const (
	RegistryDiscoveryTypeNativeType RegistryDiscoveryType = "native_type"
	RegistryDiscoveryTypeConsul     RegistryDiscoveryType = "consul"
	RegistryDiscoveryTypeEtcd       RegistryDiscoveryType = "etcd"
	RegistryDiscoveryTypeEureka     RegistryDiscoveryType = "eureka"
	RegistryDiscoveryTypeKubernetes RegistryDiscoveryType = "kubernetes"
	RegistryDiscoveryTypeNacos      RegistryDiscoveryType = "nacos"
	RegistryDiscoveryTypeZookeeper  RegistryDiscoveryType = "zookeeper"
)

type RegistryDiscoveryType string

// RegistryOptions 注册中心的配置对象
type RegistryOptions struct {
	// Address , registry center host and port ,like 127.0.0.1:8500
	Address string `mapstructure:"address" json:"address,omitempty"`
	// Scheme , like http or https
	Scheme string `mapstructure:"scheme"  json:"scheme,omitempty"`
	// Tags
	Tags []string `mapstructure:"tags"  json:"tags,omitempty"`
	// Type , registry type
	Type RegistryDiscoveryType `mapstructure:"type"  json:"type,omitempty"`
}

func NewRegistryOptions() *RegistryOptions {
	return &RegistryOptions{
		Address: "127.0.0.1:8500",
		Scheme:  "http",
	}
}

func (o *RegistryOptions) AddFlags(fs *pflag.FlagSet) {
	fs.StringVar(&o.Address, "registry.address", o.Address, "registry address .")
	fs.StringVar(&o.Scheme, "registry.scheme", o.Scheme, "registry scheme.")
	fs.StringVar((*string)(&o.Type), "registry.type", string(o.Type), "registry type.")
}

func (o *RegistryOptions) Validate() error {
	if o.Address == "" {
		return errors.New("address is empty")
	}
	if o.Scheme == "" {
		return errors.New("scheme is empty")
	}
	if o.Type == "" {
		return errors.New("type is empty")
	}
	DiscoveryType := strings.ToLower(string(o.Type))
	switch DiscoveryType {
	case string(RegistryDiscoveryTypeConsul):
	case string(RegistryDiscoveryTypeEtcd):
	case string(RegistryDiscoveryTypeEureka):
	case string(RegistryDiscoveryTypeKubernetes):
	case string(RegistryDiscoveryTypeNacos):
	case string(RegistryDiscoveryTypeZookeeper):
	default:
		errMsg := fmt.Sprintf("not supported registry type:%s", DiscoveryType)
		return errors.New(errMsg)
	}
	return nil
}
